package com.piesat.quake.common.mongo.service;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mongodb.client.result.UpdateResult;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.List;

public interface MongoService {

    /**
     * 保存一个对象到mongodb
     *
     * @param t
     * @param <T>
     * @return
     */
    <T> T save(T t);

    /**
     * 根据id删除对象
     *
     * @param t
     */
    <T> void deleteById(T t);

    /**
     * 删除所有
     *
     * @param query
     * @param entityClass
     */
    <T> void removeAll(Query query, Class<T> entityClass);

    /**
     * 通过条件查询更新数据
     *
     * @param query
     * @param update
     * @param entityClass
     * @return
     */
    <T> UpdateResult update(Query query, Update update, Class<T> entityClass);

    /**
     * 更新第一条满足条件的文档
     *
     * @param query
     * @param update
     * @param entityClass
     * @return
     */
    <T> UpdateResult updateFirst(Query query, Update update, Class<T> entityClass);

    /**
     * 新增或插入
     *
     * @param query
     * @param update
     * @param entityClass
     * @return
     */
    <T> UpdateResult upsert(Query query, Update update, Class<T> entityClass);

    /**
     * 构建update
     *
     * @param t
     * @return
     */
    <T> Update buildBaseUpdate(T t);

    /**
     * 根据id进行更新
     *
     * @param id
     * @param t
     * @param entityClass
     * @return
     */
    <T> UpdateResult updateById(String id, T t, Class<T> entityClass);

    /**
     * 根据id进行更新
     *
     * @param id
     * @param t
     * @param entityClass
     * @return
     */
    <T> UpdateResult updateById(Integer id, T t, Class<T> entityClass);

    <T> UpdateResult updateById(Integer id, Update update, Class<T> entityClass);

    /**
     * 通过条件查询实体（集合）
     *
     * @param query
     * @param entityClass
     * @return
     */
    <T> List<T> find(Query query, Class<T> entityClass);

    /**
     * 通过主键查询实体
     *
     * @param id
     * @param entityClass
     * @return
     */
    <T> T findById(Integer id, Class<T> entityClass);

    <T> T findById(String id, Class<T> entityClass);

    <T> List<T> findByIdIn(Iterable<Integer> ids, Class<T> entityClass);

    /**
     * 通过一定的条件查询一个实体
     *
     * @param query
     * @param entityClass
     * @return
     */
    <T> T findOne(Query query, Class<T> entityClass);

    /**
     * 通过条件查询实体（集合）
     *
     * @param query
     * @param entityClass
     * @param excludeFields
     * @return
     */
    <T> List<T> find(Query query, Class<T> entityClass, String... excludeFields);

    /**
     * 通过条件查询实体
     *
     * @param query
     * @param entityClass
     * @param excludeFields
     * @return
     */
    <T> T findOne(Query query, Class<T> entityClass, String... excludeFields);

    /**
     * 总记录数
     *
     * @param query
     * @param entityClass
     * @param <T>
     * @return
     */
    <T> long count(Query query, Class<T> entityClass);

    /**
     * 获取分页数据
     *
     * @param currentPage
     * @param pageSize
     * @param query
     * @param entityClass
     * @param <T>
     * @return
     */
    <T> Page<T> pageInfo(int currentPage, int pageSize, Query query, Class<T> entityClass);

    /**
     * 聚合查询
     *
     * @param aggregation
     * @param inputType
     * @param outputType
     * @param <T>
     * @return
     */
    <T> AggregationResults<T> aggregate(Aggregation aggregation, Class<?> inputType, Class<T> outputType);

    /**
     * 批量插入
     *
     * @param list
     * @param <T>
     */
    <T> void insertAll(List<T> list);

    /**
     * 批量更新
     *
     * @param query
     * @param update
     * @param entityClass
     * @param <T>
     * @return
     */
    <T> UpdateResult updateMulti(Query query, Update update, Class<T> entityClass);

}
